// Shawn Lutch
// COSC 1437 GE #1, Fall 2013
// LotteryLS.cpp

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

/* function prototypes */
int generateNumberInRange(int min, int max); // generates a number in range min to max, inclusively
int generateUniqueNumber(int numbers[], int size); // generates a number unique to the array given with size 'int size'
bool containsNumber(int numbers[], int size, int whatNumber); // returns true if 'int numbers[]' contains 'int whatNumber'
bool isTypeOneMatch(int numbers[], int origNumbers[], int size); // checks for type one match
bool isTypeTwoMatch(int numbers[], int origNumbers[], int size); // checks for type two match
void generateNumbers(int numbers[], int size); // generates six unique numbers and stores them in the array
void printNumbers(int numbers[], int size); // prints the given numbers in format "1 2 3 ..."

void main()
{
	srand(time(NULL));

	const int SIZE = 6;
	const int TOTAL_SETS = 1000000;

	int originalNumbers[SIZE] = {};

	// Generate original numbers and print them
	cout << "Generating original numbers . . . ";
	generateNumbers(originalNumbers, SIZE);
	cout << "Done.\nOriginal numbers: ";
	printNumbers(originalNumbers, SIZE);
	cout << "\n\n";

	// Generate one million random sets and tally matches
	int tempNumbers[SIZE] = {};
	int typeOneMatches = 0;
	int typeTwoMatches = 0;

	cout << "Generating one million sets of numbers . . . ";
	for (int i = 0; i < TOTAL_SETS; i++)
	{
		generateNumbers(tempNumbers, SIZE);

		if (isTypeOneMatch(tempNumbers, originalNumbers, SIZE))
			typeOneMatches++;
		if (isTypeTwoMatch(tempNumbers, originalNumbers, SIZE))
			typeTwoMatches++;
	}
	cout << "Done.\n\n";

	/* Print counts for each type of match */
	cout << "Type one matches: " << typeOneMatches << endl;
	cout << "Type two matches: " << typeTwoMatches << endl;
}

/* function definitions */

int generateNumberInRange(int min, int max)
{
	return rand() % (max - min + 1) + min;
}

int generateUniqueNumber(int numbers[], int size)
{
	int randomNumber;

	do {
		randomNumber = generateNumberInRange(0, 9);
		// continue while the given array contains the generated number
	} while (containsNumber(numbers, size, randomNumber));

	return randomNumber;
}

bool containsNumber(int numbers[], int size, int whatNumber)
{
	for (int i = 0; i < size; i++)
		if (whatNumber == numbers[i]) return true;

	return false; // if none of the numbers match
}

bool isTypeOneMatch(int numbers[], int origNumbers[], int size)
{
	for (int i = 0; i < size; i++)
		if (numbers[i] != origNumbers[i]) return false;

	return true;
}

// BUGFIX excluded type one matches from also being counted as type two matches
bool isTypeTwoMatch(int numbers[], int origNumbers[], int size)
{
	if (isTypeOneMatch(numbers, origNumbers, size)) return false;

	for (int i = 0; i < size; i++)
		if (!containsNumber(origNumbers, size, numbers[i])) return false;

	return true;
}

void generateNumbers(int numbers[], int size)
{
	for (int i = 0; i < size; i++)
		numbers[i] = generateUniqueNumber(numbers, size);
}

void printNumbers(int numbers[], int size)
{
	for (int i = 0; i < size; i++)
		cout << numbers[i] << " ";
}
